import os
import binascii
import tkinter as tk
from tkinter import filedialog, messagebox, ttk

class FileHandler:
    def __init__(self, parent_window):
        self.parent_window = parent_window
        self.file_path = None
        self.file_content = None
        self.file_type = None
        
    def select_file(self):
        """打开文件选择对话框，支持bin和hex文件"""
        file_types = [
            ("BIN files", "*.bin"),
            ("HEX files", "*.hex"),
            ("All files", "*.*")
        ]
        
        file_path = filedialog.askopenfilename(
            title="选择BIN或HEX文件",
            filetypes=file_types
        )
        
        if file_path:
            self.file_path = file_path
            self.file_type = os.path.splitext(file_path)[1].lower()
            return True
        return False
    
    def read_file(self):
        """读取选定的文件"""
        if not self.file_path:
            return False
            
        try:
            if self.file_type == '.bin':
                return self._read_bin_file()
            elif self.file_type == '.hex':
                return self._read_hex_file()
            else:
                # 尝试作为二进制文件读取
                return self._read_bin_file()
        except Exception as e:
            messagebox.showerror("文件读取错误", f"读取文件时发生错误:\n{str(e)}")
            return False
    
    def _read_bin_file(self):
        """读取二进制文件"""
        try:
            with open(self.file_path, 'rb') as file:
                self.file_content = file.read()
            return True
        except Exception as e:
            raise Exception(f"无法读取BIN文件: {str(e)}")
    
    def _read_hex_file(self):
        """读取HEX文件"""
        try:
            with open(self.file_path, 'r', encoding='utf-8') as file:
                content = file.read()
                
            # 简单验证是否为有效的HEX文件格式
            lines = content.strip().split('\n')
            for line in lines:
                if line.startswith(':') and len(line) > 10:
                    # 基本的HEX文件行验证
                    try:
                        # 验证数据长度字段
                        data_length = int(line[1:3], 16)
                        # 验证地址字段
                        address = int(line[3:7], 16)
                        # 验证记录类型
                        record_type = int(line[7:9], 16)
                    except ValueError:
                        raise Exception("HEX文件格式不正确")
            
            self.file_content = content
            return True
        except Exception as e:
            raise Exception(f"无法读取HEX文件: {str(e)}")
    
    def get_file_info(self):
        """获取文件信息"""
        if not self.file_path or self.file_content is None:
            return None
            
        file_size = os.path.getsize(self.file_path)
        file_name = os.path.basename(self.file_path)
        
        info = {
            'name': file_name,
            'path': self.file_path,
            'size': file_size,
            'type': self.file_type.upper() if self.file_type else "未知",
            'content_preview': ""
        }
        
        # 提供内容预览
        if self.file_type == '.bin':
            # 对于二进制文件，显示前几个字节的十六进制表示
            preview_bytes = self.file_content[:32]  # 前32字节
            info['content_preview'] = binascii.hexlify(preview_bytes).decode('ascii')
        elif self.file_type == '.hex':
            # 对于HEX文件，显示前几行
            lines = self.file_content.split('\n')[:5]  # 前5行
            info['content_preview'] = '\n'.join(lines)
        else:
            # 其他情况显示前100个字符
            info['content_preview'] = str(self.file_content)[:100]
            
        return info
    
    def display_file_content(self):
        """在新窗口中显示文件内容"""
        if not self.file_path or self.file_content is None:
            return
            
        # 创建新窗口显示文件内容
        content_window = tk.Toplevel(self.parent_window)
        content_window.title(f"文件内容 - {os.path.basename(self.file_path)}")
        content_window.geometry("800x600")
        
        # 创建文本框和滚动条
        text_frame = ttk.Frame(content_window)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        text_widget = tk.Text(text_frame, wrap=tk.NONE)
        text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 垂直滚动条
        v_scrollbar = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=text_widget.yview)
        v_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        text_widget.config(yscrollcommand=v_scrollbar.set)
        
        # 水平滚动条
        h_scrollbar = ttk.Scrollbar(content_window, orient=tk.HORIZONTAL, command=text_widget.xview)
        h_scrollbar.pack(side=tk.BOTTOM, fill=tk.X)
        text_widget.config(xscrollcommand=h_scrollbar.set)
        
        # 显示内容
        if self.file_type == '.bin':
            # 以十六进制格式显示二进制文件
            hex_content = binascii.hexlify(self.file_content).decode('ascii')
            # 格式化为每行16字节
            formatted_content = ""
            for i in range(0, len(hex_content), 32):
                line = hex_content[i:i+32]
                # 添加地址偏移
                offset = f"{i//2:08X}: "
                # 格式化为每字节两个字符
                formatted_line = " ".join([line[j:j+2] for j in range(0, len(line), 2)])
                formatted_content += offset + formatted_line + "\n"
            text_widget.insert(tk.END, formatted_content)
        else:
            # 直接显示文本内容
            text_widget.insert(tk.END, self.file_content)
            
        text_widget.config(state=tk.DISABLED)
